(define (umainpe:generate-residual-program o-file ann-prog goalsvv)
  (define o-port #f)
  (define pending #f)
  (define names #f)
  (define counts #f)
  (define (generate-residual-program-pe)
    (let ((s-prog (caddr ann-prog))
          (d-prog (cadr ann-prog))
          (rf (car ann-prog)))
      (let ((%%120 ($specialize-fundef ann-prog '())))
        (let ((fname %%120))
          (let ((%%121 `(,fname unquote goalsvv)))
            (let ((conf %%121))
              (set! counts '())
              (set! pending '())
              (set! names '())
              (find-name! conf)
              (choose-conf-pe)))))))
  (define (choose-conf-pe)
    (if (null? pending)
      '()
      (let ((rest (cdr pending)) (conf (car pending)))
        (set! pending rest)
        (let ((%%122 ($specialize-fundef ann-prog conf)))
          (let ((body (cadr %%122)) (dvn (car %%122)))
            (update! body)
            (let* ((fname (cdr (assoc conf names)))
                   (fundef `(,fname ,dvn = ,body)))
              (print-fundef fundef)
              (choose-conf-pe)))))))
  (define (generate-residual-program-gn)
    (let ((%%123 ($specialize-fundef-$1 '())))
      (let ((fname %%123))
        (let ((%%124 `(,fname unquote goalsvv)))
          (let ((conf %%124))
            (set! counts '())
            (set! pending '())
            (set! names '())
            (find-name! conf)
            (choose-conf-gn))))))
  (define (choose-conf-gn)
    (if (null? pending)
      '()
      (let ((rest (cdr pending)) (conf (car pending)))
        (set! pending rest)
        (let ((%%125 ($specialize-fundef-$1 conf)))
          (let ((body (cadr %%125)) (dvn (car %%125)))
            (update! body)
            (let* ((fname (cdr (assoc conf names)))
                   (fundef `(,fname ,dvn = ,body)))
              (print-fundef fundef)
              (choose-conf-gn)))))))
  (define (print-fundef fundef)
    (display "*")
    (pretty-print fundef o-port)
    (newline o-port)
    (newline o-port))
  (define (update! exp)
    (cond ((symbol? exp) #f)
          ((equal? (car exp) 'quote) (let ((const (cadr exp))) #f))
          ((equal? (car exp) 'call)
           (let ((exp* (cddr exp)) (conf (cadr exp)))
             (for-each update! exp*)
             (set-car! (cdr exp) (find-name! conf))))
          ((equal? (car exp) 'xcall)
           (let ((exp* (cddr exp)) (fname (cadr exp)))
             (for-each update! exp*)))
          (else
           (let ((exp* (cdr exp)) (op (car exp))) (for-each update! exp*)))))
  (define (find-name! conf)
    (let ((%%126 (assoc conf names)))
      (let ((conf-descr %%126) (fname (car conf)))
        (if (not conf-descr)
          (begin
            (set! conf-descr `(,conf unquote (make-fname! fname)))
            (set! names `(,conf-descr unquote names))
            (set! pending `(,conf unquote pending))))
        (cdr conf-descr))))
  (define (make-fname! fname)
    (string->symbol
      (string-append
        (symbol->string fname)
        "-$"
        (number->string (get-free-count! fname)))))
  (define (get-free-count! fname)
    (let ((fname-descr (assq fname counts)))
      (if fname-descr
        (let ((count (+ 1 (cdr fname-descr))))
          (set-cdr! fname-descr count)
          count)
        (begin (set! counts `((,fname . 1) unquote counts)) 1))))
  (set! o-port (open-output-file o-file))
  (if (null? ann-prog)
    (generate-residual-program-gn)
    (generate-residual-program-pe))
  (close-output-port o-port))

(define xapply
  (let ((proc-list '()))
    (lambda (fname args)
      (let ((fname/proc (assq fname proc-list)))
        (if fname/proc
          (apply (cdr fname/proc) args)
          (let ((proc (eval-t fname)))
            (set! proc-list `((,fname unquote proc) unquote proc-list))
            (apply proc args)))))))

